the messenging aspect of herbstluftwm via shell scripts and herbstclient allow extending the window manager behaviour. One added benefit is that it is fairly difficult to bork the actual window manager—at least, I haven’t been able to do so. Illegal herbstclient commands just fail gracefully—no harm done. No recompilation required. And you can test out code snippets in a terminal window before committing the code to the autostart or scripts to be spawned.
is implemented to follow (focus) the current tag or retain focus of the current monitor, dependent on whether the monitor tag is pushed in the direction of monitor (switch focus)—corresponding to left/right bracket—or pulled from the adjacent monitor (retain focus)..
#!/bin/sh
function swap_to() {
swap_monitors=$(herbstclient get swap_monitors_to_get_tag)
herbstclient set swap_monitors_to_get_tag 1
if [[ $@ = 0 ]]; then
herbstclient chain . lock . focus_monitor 1 . use $tag0 . focus_monitor 0 . use $tag1 . unlock
else
herbstclient chain . lock . focus_monitor 0 . use $tag1 . focus_monitor 1 . use $tag0 . unlock
fi
herbstclient set swap_monitors_to_get_tag $swap_monitors
}
direction=$@
focus=$(herbstclient list_monitors | grep '\[FOCUS\]' | cut -d: -f1)
tag0=$(herbstclient list_monitors | grep '^0:' | cut -d'"' -f2)
tag1=$(herbstclient list_monitors | grep '^1:' | cut -d'"' -f2)
if [[ $focus = $direction ]]; then
[[ $focus = 0 ]] && swap_to 0 || swap_to 1
else
[[ $focus = 0 ]] && swap_to 1 || swap_to 0
fi
swap_monitors_to_get_tag is set to 1 to enable the tag swap of existing views.
This ultimately saves me potentially one meager keystroke combination— selecting the monitor in focus—and needing to know the monitor tag I wish to swap! Lazy I know but it’s handy. And it is one less thing— the tags in view—to need to track in the back of your head. The keybinds match the left/right position of the monitor placement to the left/right bracket..
herbstclient keybind Mod1-Control-bracketleft spawn swap_monitors 1
herbstclient keybind Mod1-Control-bracketright spawn swap_monitors 0
is similar in action to swap_monitors but moves a window to the adjacent monitor, following (focus) or retaining focus of the current monitor depending on the direction (left/right bracket) of the window movement..
#!/bin/sh
direction=$@
focus=$(herbstclient list_monitors | grep '\[FOCUS\]' | cut -d: -f1)
if [[ $focus = $direction ]]; then
if [[ $focus = 0 ]]; then
herbstclient and . lock . shift_to_monitor 1 . focus_monitor 0 . unlock
else
herbstclient and . lock . shift_to_monitor 0 . focus_monitor 1 . unlock
fi
else
if [[ $focus = 0 ]]; then
herbstclient and . lock . shift_to_monitor 1 . focus_monitor 1 . unlock
else
herbstclient and . lock . shift_to_monitor 0 . focus_monitor 0 . unlock
fi
fi
As above, the keybinds match the left/right position of the monitor placement to the left/right bracket..
herbstclient keybind Mod1-Shift-bracketleft spawn swap_window 1
herbstclient keybind Mod1-Shift-bracketright spawn swap_window 0
is something transcribed from my bspwm customizations. Most often in herbstluftwm, it is simple enough to set the frame layout to max for the window in focus which, effectively hides the other windows in the frame.
But sometimes, especially in grid layout, it is handy to temporarily minimize (hide) a window or two to quickly resize the remaining windows of the frame, keeping them all in view. Rather than follow common tiling window manager convention to move windows to desktop (tag) “0” or an adjacent monitor, a (tick) ‘tag is added to hold and restore windows from..
#!/bin/sh
tag=$(herbstclient list_monitors | grep '\[FOCUS\]' | cut -d'"' -f2)
if [[ $@ = +1 ]]; then
herbstclient dump “‘$tag” || herbstclient add “‘$tag”
herbstclient move “‘$tag”
else
herbstclient dump “‘$tag” && herbstclient chain . lock . use “‘$tag” . move $tag . use $tag . unlock
fi
With simple keybinds, any number of windows per tag can be effectively minimized and restored in order..
hc keybind $Mod-m spawn hide_window +1
hc keybind $Mod-Shift-m spawn hide_window -1
Note: the window(s) are restored to the current frame in focus of the tag.
is a persistent terminal that can be toggled (hide/unhide from the tag in focus) or pulled into view from any desktop (tag). Hence, you can open the scratchpad in any tag, switch to another and pull it into view on the new tag in focus—regardless of whether the scratchpad is visible or not.
It is a lightweight implementation and acts like an ordinary window (versus the virtual monitor overlay example provided in the herbstluftwm contributions)..
#!/bin/sh
scratchpad=/tmp/herbstluftwm:scratchpad
if xdotool search --onlyvisible --classname 'scratchpad'; then
if [[ $(herbstclient list_monitors | grep ‘[FOCUS]’ | cut -d’”’ -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep ‘s - tag’ | awk ‘{ print $5 }’) ]]; then
xdotool search –onlyvisible –classname ‘scratchpad’ windowunmap
exit
fi
fi
if [[ -f $scratchpad ]]; then
if ! herbstclient bring $(cat $scratchpad); then
xdotool search –classname ‘scratchpad’ windowmap && exit
fi
fi
if ! xdotool search --classname 'scratchpad' windowmap; then
urxvt -title ‘scratchpad’ -name ‘scratchpad’ -pe tabbed &
xdotool search –sync –onlyvisible –classname ‘scratchpad’
herbstclient attr clients.focus.winid > $scratchpad
fi
I use the scratchpad a lot—the urxvt tabbed perl extension can reduce the need for extra terminal windows and the persistent content is useful throughout a session—seldom using separate terminal windows, so designate the common terminal keybinds as such..
herbstclient keybind Mod1-Return spawn scratchpad
herbstclient keybind Mod1-Shift-Return spawn urxvt
which will open the scratchpad on the desktop, unless it is already in view (in which case, it will be hidden). Extra terminals are always available for times it is handy to work with terminals side-by-side.